package com.ruoyi.business.service.fission.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.ruoyi.business.domain.dto.admin.fission.*;
import com.ruoyi.business.domain.fission.*;
import com.ruoyi.business.domain.koc.TbUserThirdIdentity;
import com.ruoyi.business.domain.vo.fission.admin.FissionActivitySysDetailVO;
import com.ruoyi.business.domain.vo.fission.api.WecomChatGroupVO;
import com.ruoyi.business.domain.wecom.TbWecomChatGroup;
import com.ruoyi.business.domain.wecom.TbWecomChatGroupJoinWayConf;
import com.ruoyi.business.mapper.fission.TbWecomChatGroupFissionMapper;
import com.ruoyi.business.service.fission.*;
import com.ruoyi.business.service.koc.ITbUserThirdIdentityService;
import com.ruoyi.business.service.wecom.ITbWecomChatGroupJoinWayConfService;
import com.ruoyi.business.service.wecom.ITbWecomChatGroupService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.fission.*;
import com.ruoyi.common.enums.wecom.WecomSceneEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.HttpClientUtil;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.service.IOssStrategy;
import com.ruoyi.weixin.config.WxMaConfiguration;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.external.WxCpGroupJoinWayInfo;
import me.chanjar.weixin.cp.bean.external.WxCpGroupJoinWayResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 企业微信群裂变活动 服务实现类
 * </p>
 *
 * @author
 * @since 2024-01-20
 */
@Service
public class TbWecomChatGroupFissionServiceImpl extends ServiceImpl<TbWecomChatGroupFissionMapper, TbWecomChatGroupFission> implements ITbWecomChatGroupFissionService {

    @Resource
    private ITbWecomChatGroupFissionRewardSettingService tbWecomChatGroupFissionRewardSettingService;

    @Resource
    private ITbWecomChatGroupFissionPosterSettingService tbWecomChatGroupFissionPosterSettingService;

    @Resource
    private ITbWecomChatGroupFissionMainSettingService tbWecomChatGroupFissionMainSettingService;

    @Resource
    private ITbWecomChatGroupFissionGroupSettingService tbWecomChatGroupFissionGroupSettingService;

    @Resource
    private ITbWecomChatGroupJoinWayConfService tbWecomChatGroupJoinWayConfService;

    @Resource
    private ITbWecomChatGroupService tbWecomChatGroupService;

    @Resource
    private ITbWecomChatGroupFissionSceneService tbWecomChatGroupFissionSceneService;

    @Resource
    private ITbWecomChatGroupFissionInviteService tbWecomChatGroupFissionInviteService;

    @Resource
    private ITbUserThirdIdentityService tbUserThirdIdentityService;

    @Resource
    private WxCpService wxCpService;

    @Value("${wechat.miniapp.configs[0].appid}")
    private String appid;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sysAdd(FissionActivitySysAddDTO fissionActivitySysAddDTO) {
        long fissionId = IdWorker.getId();
        // 添加主配置信息
        FissionMainInfoSysAddDTO mainInfo = fissionActivitySysAddDTO.getMainInfo();
        TbWecomChatGroupFission tbWecomChatGroupFission = new TbWecomChatGroupFission();
        tbWecomChatGroupFission.setId(fissionId);
        tbWecomChatGroupFission.setName(mainInfo.getName());
        tbWecomChatGroupFission.setIntroduction(mainInfo.getIntroduction());
        tbWecomChatGroupFission.setEndTime(mainInfo.getEndTime());

        tbWecomChatGroupFission.setRankingListEnable(mainInfo.getRankingListEnable());
        if (mainInfo.getRankingListEnable() == 1) {
            tbWecomChatGroupFission.setRankingListCount(mainInfo.getRankingListCount());
        }
        tbWecomChatGroupFission.setStatus(GroupFissionStatusEnum.NOT_STARTED.getCode());
        tbWecomChatGroupFission.setCreateTime(new Date());
        tbWecomChatGroupFission.setCreateBy(LoginHelper.getUsername());
        // 添加主配置信息
        FissionMainSettingSysAddDTO mainSettingInfo = fissionActivitySysAddDTO.getMainSettingInfo();
        TbWecomChatGroupFissionMainSetting tbWecomChatGroupFissionMainSetting = new TbWecomChatGroupFissionMainSetting();
        tbWecomChatGroupFissionMainSetting.setId(IdWorker.getId());
        tbWecomChatGroupFissionMainSetting.setFissionId(fissionId);
        tbWecomChatGroupFissionMainSetting.setRewardNumberZeroEndEnable(mainSettingInfo.getRewardNumberZeroEndEnable());

        tbWecomChatGroupFissionMainSetting.setShowRewardNumberEnable(mainSettingInfo.getShowRewardNumberEnable());
        if (mainSettingInfo.getShowRewardNumberEnable() == 1) {
            tbWecomChatGroupFissionMainSetting.setRewardNumber(mainSettingInfo.getRewardNumber());
        }
        tbWecomChatGroupFissionMainSetting.setOnlyNewUser(mainSettingInfo.getOnlyNewUser());
        tbWecomChatGroupFissionMainSetting.setExitGroupInvalid(mainSettingInfo.getExitGroupInvalid());
        tbWecomChatGroupFissionMainSetting.setCreateTime(new Date());
        tbWecomChatGroupFissionMainSetting.setCreateBy(LoginHelper.getUsername());
        tbWecomChatGroupFissionMainSettingService.save(tbWecomChatGroupFissionMainSetting);
        // 添加活动奖励配置信息
        List<TbWecomChatGroupFissionRewardSetting> tbWecomChatGroupFissionRewardSettings = new ArrayList<>();
        List<FissionRewardSettingSysAddDTO> mainRewardSettingInfos = fissionActivitySysAddDTO.getMainRewardSettingInfos();
        for (FissionRewardSettingSysAddDTO rewardSetting : mainRewardSettingInfos) {
            TbWecomChatGroupFissionRewardSetting tbWecomChatGroupFissionRewardSetting = new TbWecomChatGroupFissionRewardSetting();
            tbWecomChatGroupFissionRewardSetting.setId(IdWorker.getId());
            tbWecomChatGroupFissionRewardSetting.setFissionId(fissionId);
            tbWecomChatGroupFissionRewardSetting.setNotifyRuleName(rewardSetting.getNotifyRuleName());
            tbWecomChatGroupFissionRewardSetting.setRewardName(rewardSetting.getRewardName());
            tbWecomChatGroupFissionRewardSetting.setRewardDesc(rewardSetting.getRewardDesc());
            tbWecomChatGroupFissionRewardSetting.setRewardPic(rewardSetting.getRewardPic());
            tbWecomChatGroupFissionRewardSetting.setNotifyRule(rewardSetting.getNotifyRule());
            tbWecomChatGroupFissionRewardSetting.setRewardType(rewardSetting.getRewardType());
            if (Objects.equals(rewardSetting.getRewardType(), RewardTypeEnum.POINTS.getCode())) {
                tbWecomChatGroupFissionRewardSetting.setRewardPoints(rewardSetting.getRewardPoints());
            }
            if (Objects.equals(rewardSetting.getRewardType(), RewardTypeEnum.PRODUCT.getCode())) {
                tbWecomChatGroupFissionRewardSetting.setRewardProducts(rewardSetting.getRewardProducts());
            }

            tbWecomChatGroupFissionRewardSetting.setRewardCountEnable(rewardSetting.getRewardCountEnable());
            if (rewardSetting.getRewardCountEnable() == 1) {
                tbWecomChatGroupFissionRewardSetting.setRewardCount(rewardSetting.getRewardCount());
            }
            tbWecomChatGroupFissionRewardSetting.setCreateTime(new Date());
            tbWecomChatGroupFissionRewardSetting.setCreateBy(LoginHelper.getUsername());
            tbWecomChatGroupFissionRewardSettings.add(tbWecomChatGroupFissionRewardSetting);
        }
        // 插入奖励配置
        tbWecomChatGroupFissionRewardSettingService.saveBatch(tbWecomChatGroupFissionRewardSettings);
        // 插入活动海报配置
        FissionPosterSettingSysAddDTO mainPosterSettingInfo = fissionActivitySysAddDTO.getMainPosterSettingInfo();
        TbWecomChatGroupFissionPosterSetting tbWecomChatGroupFissionPosterSetting = new TbWecomChatGroupFissionPosterSetting();
        tbWecomChatGroupFissionPosterSetting.setId(IdWorker.getId());
        tbWecomChatGroupFissionPosterSetting.setFissionId(fissionId);
        tbWecomChatGroupFissionPosterSetting.setName(mainPosterSettingInfo.getName());
        tbWecomChatGroupFissionPosterSetting.setUserAvatarShowEnable(mainPosterSettingInfo.getUserAvatarShowEnable());
        tbWecomChatGroupFissionPosterSetting.setUserNicknameShowEnable(mainPosterSettingInfo.getUserNicknameShowEnable());
        tbWecomChatGroupFissionPosterSetting.setPosterUrl(mainPosterSettingInfo.getPosterUrl());
        tbWecomChatGroupFissionPosterSetting.setPosterSpeechArtEnable(mainPosterSettingInfo.getPosterSpeechArtEnable());
        tbWecomChatGroupFissionPosterSetting.setPosterSpeechArtContent(mainPosterSettingInfo.getPosterSpeechArtContent());
        tbWecomChatGroupFissionPosterSetting.setAssistProgressButton(mainPosterSettingInfo.getAssistProgressButton());
        tbWecomChatGroupFissionPosterSetting.setShareButton(mainPosterSettingInfo.getShareButton());
        tbWecomChatGroupFissionPosterSetting.setCreateTime(new Date());
        tbWecomChatGroupFissionPosterSetting.setCreateBy(LoginHelper.getUsername());
        tbWecomChatGroupFissionPosterSettingService.save(tbWecomChatGroupFissionPosterSetting);
        // 添加活动群组
        List<FissionGroupSettingSysAddDTO> mainGroupSettingInfos = fissionActivitySysAddDTO.getMainGroupSettingInfos();
        List<TbWecomChatGroupFissionGroupSetting> tbWecomChatGroupFissionGroupSettings = new ArrayList<>();
        for (FissionGroupSettingSysAddDTO mainGroupSettingInfo : mainGroupSettingInfos) {
            TbWecomChatGroupFissionGroupSetting tbWecomChatGroupFissionGroupSetting = new TbWecomChatGroupFissionGroupSetting();
            tbWecomChatGroupFissionGroupSetting.setId(IdWorker.getId());
            tbWecomChatGroupFissionGroupSetting.setFissionId(fissionId);
            tbWecomChatGroupFissionGroupSetting.setChatGroupOrder(mainGroupSettingInfo.getChatGroupOrder());
            tbWecomChatGroupFissionGroupSetting.setChatId(mainGroupSettingInfo.getChatId());
            tbWecomChatGroupFissionGroupSetting.setChatQrCodeGetType(mainGroupSettingInfo.getChatQrCodeGetType());
            if (Objects.equals(mainGroupSettingInfo.getChatQrCodeGetType(), ChatQrCodeGetTypeEnum.MANUAL.getCode())) {
                tbWecomChatGroupFissionGroupSetting.setChatQrCode(mainGroupSettingInfo.getChatQrCode());
                tbWecomChatGroupFissionGroupSetting.setChatQrCodeCreateTime(new Date());
            } else {
                // 自动生成群活码
                TbWecomChatGroupJoinWayConf tbWecomChatGroupJoinWayConf = tbWecomChatGroupJoinWayConfService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupJoinWayConf.class)
                    .eq(TbWecomChatGroupJoinWayConf::getChatId, mainGroupSettingInfo.getChatId()));
                if (ObjectUtils.isEmpty(tbWecomChatGroupJoinWayConf)) {
                    // 自动获取群二维码
                    WxCpGroupJoinWayInfo wxCpGroupJoinWayInfo = new WxCpGroupJoinWayInfo();
                    WxCpGroupJoinWayInfo.JoinWay joinWaySet = new WxCpGroupJoinWayInfo.JoinWay();
                    joinWaySet.setAutoCreateRoom(Constants.FALSE_0);
                    // 1 - 群的小程序插件
                    // 2 - 群的二维码插件
                    joinWaySet.setScene(WecomSceneEnum.QR_CODE.getCode());
                    List<String> chatIds = new ArrayList<>();
                    chatIds.add(mainGroupSettingInfo.getChatId());
                    joinWaySet.setChatIdList(chatIds);
                    wxCpGroupJoinWayInfo.setJoinWay(joinWaySet);
                    WxCpGroupJoinWayResult wxCpGroupJoinWayResult;
                    try {
                        wxCpGroupJoinWayResult = wxCpService.getExternalContactService().addJoinWay(wxCpGroupJoinWayInfo);
                    } catch (WxErrorException e) {
                        throw new RuntimeException(e);
                    }
                    WxCpGroupJoinWayInfo joinWay;
                    try {
                        joinWay = wxCpService.getExternalContactService().getJoinWay(wxCpGroupJoinWayResult.getConfigId());
                    } catch (WxErrorException e) {
                        throw new RuntimeException(e);
                    }
                    tbWecomChatGroupFissionGroupSetting.setConfigId(joinWay.getJoinWay().getConfigId());
                    tbWecomChatGroupFissionGroupSetting.setChatQrCode(joinWay.getJoinWay().getQrCode());
                    tbWecomChatGroupFissionGroupSetting.setChatQrCodeCreateTime(new Date());
                    // 插入配置表
                    TbWecomChatGroupJoinWayConf groupjoinWayConf = new TbWecomChatGroupJoinWayConf();
                    groupjoinWayConf.setId(IdWorker.getId());
                    groupjoinWayConf.setConfId(joinWay.getJoinWay().getConfigId());
                    groupjoinWayConf.setChatId(mainGroupSettingInfo.getChatId());
                    groupjoinWayConf.setScene(WecomSceneEnum.QR_CODE.getCode());
                    groupjoinWayConf.setAutoCreateRoom(Constants.FALSE_0);
                    groupjoinWayConf.setChatIdList(String.join(",", joinWay.getJoinWay().getChatIdList()));
                    groupjoinWayConf.setQrCode(joinWay.getJoinWay().getQrCode());
                    groupjoinWayConf.setCreateTime(new Date());
                } else {
                    tbWecomChatGroupFissionGroupSetting.setConfigId(tbWecomChatGroupJoinWayConf.getConfId());
                    tbWecomChatGroupFissionGroupSetting.setChatQrCode(tbWecomChatGroupJoinWayConf.getQrCode());
                    tbWecomChatGroupFissionGroupSetting.setChatQrCodeCreateTime(tbWecomChatGroupJoinWayConf.getCreateTime());
                }

            }
            tbWecomChatGroupFissionGroupSetting.setUserLimit(mainGroupSettingInfo.getUserLimit());
            tbWecomChatGroupFissionGroupSetting.setGroupWelcomeTemplateId(mainGroupSettingInfo.getGroupWelcomeTemplateId());
            tbWecomChatGroupFissionGroupSetting.setCreateTime(new Date());
            tbWecomChatGroupFissionGroupSetting.setCreateBy(LoginHelper.getUsername());
            tbWecomChatGroupFissionGroupSettings.add(tbWecomChatGroupFissionGroupSetting);
        }
        tbWecomChatGroupFissionGroupSettingService.saveBatch(tbWecomChatGroupFissionGroupSettings);
        return this.save(tbWecomChatGroupFission);
    }

    @Override
    public TableDataInfo<TbWecomChatGroupFission> sysPageQuery(String name, PageQuery pageQuery) {
        LambdaQueryWrapper<TbWecomChatGroupFission> qwl = Wrappers.lambdaQuery(TbWecomChatGroupFission.class)
            .like(StringUtils.isNotEmpty(name), TbWecomChatGroupFission::getName, name)
            .orderByDesc(TbWecomChatGroupFission::getCreateTime);
        Page<TbWecomChatGroupFission> page = this.page(pageQuery.build(), qwl);
        return TableDataInfo.build(page);
    }

    @Override
    public FissionActivitySysDetailVO sysSelectDetail(Long fissionId) {
        TbWecomChatGroupFission tbWecomChatGroupFission = this.getById(fissionId);
        List<TbWecomChatGroupFissionRewardSetting> tbWecomChatGroupFissionRewardSettings = tbWecomChatGroupFissionRewardSettingService.list(Wrappers.lambdaQuery(TbWecomChatGroupFissionRewardSetting.class).eq(TbWecomChatGroupFissionRewardSetting::getFissionId, fissionId)
            .orderByDesc(TbWecomChatGroupFissionRewardSetting::getNotifyRule));
        TbWecomChatGroupFissionMainSetting tbWecomChatGroupFissionMainSetting = tbWecomChatGroupFissionMainSettingService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupFissionMainSetting.class).eq(TbWecomChatGroupFissionMainSetting::getFissionId, fissionId));
        TbWecomChatGroupFissionPosterSetting tbWecomChatGroupFissionPosterSetting = tbWecomChatGroupFissionPosterSettingService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupFissionPosterSetting.class).eq(TbWecomChatGroupFissionPosterSetting::getFissionId, fissionId));
        List<TbWecomChatGroupFissionGroupSetting> tbWecomChatGroupFissionGroupSettings = tbWecomChatGroupFissionGroupSettingService.list(Wrappers.lambdaQuery(TbWecomChatGroupFissionGroupSetting.class)
            .eq(TbWecomChatGroupFissionGroupSetting::getFissionId, fissionId)
        );
        List<String> chatIds = tbWecomChatGroupFissionGroupSettings.stream().map(TbWecomChatGroupFissionGroupSetting::getChatId).collect(Collectors.toList());

        List<TbWecomChatGroup> tbWecomChatGroup = tbWecomChatGroupService.list(Wrappers.lambdaQuery(TbWecomChatGroup.class).in(TbWecomChatGroup::getChatId, chatIds));
        // 转map
        // 转换为 Map<chatId, TbWecomChatGroup>
        Map<String, TbWecomChatGroup> chatGroupMap = tbWecomChatGroup.stream()
            .collect(Collectors.toMap(TbWecomChatGroup::getChatId, Function.identity()));
        tbWecomChatGroupFissionGroupSettings.forEach(setting -> {
            setting.setTbWecomChatGroup(chatGroupMap.get(setting.getChatId()));
        });
        return FissionActivitySysDetailVO.builder().mainInfo(tbWecomChatGroupFission).mainGroupSettingInfos(tbWecomChatGroupFissionGroupSettings).mainPosterSettingInfo(tbWecomChatGroupFissionPosterSetting).mainSettingInfo(tbWecomChatGroupFissionMainSetting).mainRewardSettingInfos(tbWecomChatGroupFissionRewardSettings).build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sysRemove(Long fissionId) {
        TbWecomChatGroupFission byId = this.getById(fissionId);
        if (!Objects.equals(byId.getStatus(), GroupFissionStatusEnum.NOT_STARTED.getCode())) {
            throw new ServiceException("活动已开始不允许删除");
        }
        this.removeById(fissionId);
        tbWecomChatGroupFissionRewardSettingService.remove(Wrappers.lambdaQuery(TbWecomChatGroupFissionRewardSetting.class).eq(TbWecomChatGroupFissionRewardSetting::getFissionId, fissionId));
        tbWecomChatGroupFissionMainSettingService.remove(Wrappers.lambdaQuery(TbWecomChatGroupFissionMainSetting.class).eq(TbWecomChatGroupFissionMainSetting::getFissionId, fissionId));
        tbWecomChatGroupFissionRewardSettingService.remove(Wrappers.lambdaQuery(TbWecomChatGroupFissionRewardSetting.class).eq(TbWecomChatGroupFissionRewardSetting::getFissionId, fissionId));
        tbWecomChatGroupFissionPosterSettingService.remove(Wrappers.lambdaQuery(TbWecomChatGroupFissionPosterSetting.class).eq(TbWecomChatGroupFissionPosterSetting::getFissionId, fissionId));
        tbWecomChatGroupFissionGroupSettingService.remove(Wrappers.lambdaQuery(TbWecomChatGroupFissionGroupSetting.class).eq(TbWecomChatGroupFissionGroupSetting::getFissionId, fissionId));
        return tbWecomChatGroupFissionGroupSettingService.remove(Wrappers.lambdaQuery(TbWecomChatGroupFissionGroupSetting.class).eq(TbWecomChatGroupFissionGroupSetting::getFissionId, fissionId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sysStart(Long fissionId) {
        TbWecomChatGroupFission tbWecomChatGroupFission = this.getById(fissionId);
        //生成小程序活动二维码
        long scene = IdWorker.getId();
        WxMaService wxMaService = WxMaConfiguration.getMaService(appid);
        String accessToken;
        try {
            accessToken = wxMaService.getAccessToken();
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        Map<String, String> postParam = new HashMap<>();
        postParam.put(Constants.WX_XCY_ACCESS_TOKEN, accessToken);
        Map<String, Object> jsonParamMap = new HashMap<>();
        jsonParamMap.put("scene", String.valueOf(scene));
        jsonParamMap.put("page", Constants.MINI_APP_SHARE_PAGE);
        jsonParamMap.put("check_path", false);
        jsonParamMap.put("env_version", "release");
        jsonParamMap.put("width", 430);
        jsonParamMap.put("auto_color", false);
        try {
            byte[] imageBytes = HttpClientUtil.doPostAndGetBytes(Constants.WX_XCY_Q_CODE, postParam, jsonParamMap);
            // 检查是否是错误响应（微信错误响应通常是JSON格式）
            if (imageBytes.length > 0 && imageBytes[0] == (byte) '{') {
                String errorResponse = new String(imageBytes, StandardCharsets.UTF_8);
                JsonObject jsonResponse = JsonParser.parseString(errorResponse).getAsJsonObject();
                if (jsonResponse.has("errcode")) {
                    int errcode = jsonResponse.get("errcode").getAsInt();
                    String errmsg = jsonResponse.get("errmsg").getAsString();
                    throw new RuntimeException("微信接口错误: " + errcode + " - " + errmsg);
                }
            }
            // 上传oss
            IOssStrategy storage = OssFactory.instance();
            UploadResult uploadResult = storage.uploadSuffix(imageBytes, "png", "image/png");
            // 更新
            tbWecomChatGroupFission.setEntryUrl(uploadResult.getUrl());
            this.updateById(tbWecomChatGroupFission);
            TbWecomChatGroupFissionScene tbWecomChatGroupFissionScene = new TbWecomChatGroupFissionScene();
            tbWecomChatGroupFissionScene.setId(scene);
            tbWecomChatGroupFissionScene.setName(String.valueOf(scene));
            tbWecomChatGroupFissionScene.setType(FissionSceneTypeEnum.ADMIN_SHARE.getCode());
            tbWecomChatGroupFissionScene.setFissionId(fissionId);
            tbWecomChatGroupFissionScene.setScene(String.valueOf(scene));
            tbWecomChatGroupFissionScene.setQrCodeUrl(uploadResult.getUrl());
            tbWecomChatGroupFissionSceneService.save(tbWecomChatGroupFissionScene);
        } catch (RuntimeException | IOException e) {
            throw new RuntimeException(e);
        }
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String shareQrCode(Long userId, Long fissionId, String envVersion) {
        // 查询用户是否已经生成过该活动的分享二维码
        TbWecomChatGroupFissionScene tbWecomChatGroupFissionScene = tbWecomChatGroupFissionSceneService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupFissionScene.class)
            .eq(TbWecomChatGroupFissionScene::getFissionId, fissionId)
            .eq(TbWecomChatGroupFissionScene::getType, FissionSceneTypeEnum.USER_SHARE.getCode())
            .eq(TbWecomChatGroupFissionScene::getUserId, userId));
        if (ObjectUtil.isNotEmpty(tbWecomChatGroupFissionScene)) {
            return tbWecomChatGroupFissionScene.getQrCodeUrl();
        }

        WxMaService wxMaService = WxMaConfiguration.getMaService(appid);
        String accessToken;
        try {
            accessToken = wxMaService.getAccessToken();
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        // 插入场景值表
        long scene = IdWorker.getId();
        UploadResult uploadResult;
        Map<String, String> postParam = new HashMap<>();
        postParam.put(Constants.WX_XCY_ACCESS_TOKEN, accessToken);
        Map<String, Object> jsonParamMap = new HashMap<>();
        jsonParamMap.put("scene", scene);
        jsonParamMap.put("page", Constants.MINI_APP_SHARE_PAGE);
        jsonParamMap.put("check_path", false);
        jsonParamMap.put("env_version", envVersion);
        jsonParamMap.put("width", 430);
        jsonParamMap.put("auto_color", false);
        try {
            byte[] imageBytes = HttpClientUtil.doPostAndGetBytes(Constants.WX_XCY_Q_CODE, postParam, jsonParamMap);
            // 检查是否是错误响应（微信错误响应通常是JSON格式）
            if (imageBytes.length > 0 && imageBytes[0] == (byte) '{') {
                String errorResponse = new String(imageBytes, StandardCharsets.UTF_8);
                JsonObject jsonResponse = JsonParser.parseString(errorResponse).getAsJsonObject();
                if (jsonResponse.has("errcode")) {
                    int errcode = jsonResponse.get("errcode").getAsInt();
                    String errmsg = jsonResponse.get("errmsg").getAsString();
                    throw new RuntimeException("微信接口错误: " + errcode + " - " + errmsg);
                }
            }
            // 上传 到 oss
            IOssStrategy storage = OssFactory.instance();
            uploadResult = storage.uploadSuffix(imageBytes, "png", "image/png");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        TbWecomChatGroupFissionScene add = new TbWecomChatGroupFissionScene();
        add.setId(scene);
        add.setName(String.valueOf(scene));
        add.setType(FissionSceneTypeEnum.USER_SHARE.getCode());
        add.setFissionId(fissionId);
        add.setUserId(userId);
        add.setScene(String.valueOf(scene));
        add.setQrCodeUrl(uploadResult.getUrl());
        add.setCreateTime(new Date());
        tbWecomChatGroupFissionSceneService.save(add);
        return uploadResult.getUrl();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WecomChatGroupVO queryChatGroupQrCode(Long userId, String scene) {
        // 根据场景值查询
        TbWecomChatGroupFissionScene tbWecomChatGroupFissionScene = tbWecomChatGroupFissionSceneService.getById(scene);
        // 群裂变活动id
        Long fissionId = tbWecomChatGroupFissionScene.getFissionId();
        // 分享人id
        Long shareUserId = tbWecomChatGroupFissionScene.getUserId();
        // 根据 fissionId 查询群裂变活动是否开启
        TbWecomChatGroupFission tbWecomChatGroupFission = this.getById(fissionId);
        if (ObjectUtil.isEmpty(tbWecomChatGroupFission)) {
            throw new ServiceException("场景值参数有误");
        }
        if (!tbWecomChatGroupFission.getStatus().equals(GroupFissionStatusEnum.IN_PROGRESS.getCode())) {
            throw new ServiceException("不在活动范围时间");
        }
        WecomChatGroupVO wecomChatGroupVO = tbWecomChatGroupFissionGroupSettingService.queryChatGroupQrCode(fissionId);
        if (ObjectUtil.isNotEmpty(wecomChatGroupVO)) {
            // 保存邀请关系
            if (Objects.equals(FissionSceneTypeEnum.USER_SHARE.getCode(), tbWecomChatGroupFissionScene.getType())
                || Objects.equals(FissionSceneTypeEnum.ONLY_SHARE.getCode(), tbWecomChatGroupFissionScene.getType())) {
                // 用户id userId
                List<TbWecomChatGroupFissionInvite> tbWecomChatGroupFissionInvites = tbWecomChatGroupFissionInviteService.list(Wrappers.lambdaQuery(TbWecomChatGroupFissionInvite.class)
                    .eq(TbWecomChatGroupFissionInvite::getFissionId, fissionId)
                    .eq(TbWecomChatGroupFissionInvite::getInviterUserId, shareUserId)
                    .eq(TbWecomChatGroupFissionInvite::getUserId, userId));
                if (CollectionUtils.isEmpty(tbWecomChatGroupFissionInvites)) {
                    TbUserThirdIdentity userThirdIdentity = tbUserThirdIdentityService.getOne(Wrappers.lambdaQuery(TbUserThirdIdentity.class).eq(TbUserThirdIdentity::getUserId, userId));

                    TbUserThirdIdentity shareUserIdThirdIdentity = tbUserThirdIdentityService.getOne(Wrappers.lambdaQuery(TbUserThirdIdentity.class).eq(TbUserThirdIdentity::getUserId, shareUserId));
                    // 建立邀请关系
                    TbWecomChatGroupFissionInvite tbWecomChatGroupFissionInvite = new TbWecomChatGroupFissionInvite();
                    tbWecomChatGroupFissionInvite.setId(IdWorker.getId());
                    tbWecomChatGroupFissionInvite.setUserId(userId);
                    tbWecomChatGroupFissionInvite.setUserUnionId(userThirdIdentity.getIdentityUnionId());
                    tbWecomChatGroupFissionInvite.setInviterUserId(shareUserId);
                    tbWecomChatGroupFissionInvite.setInviterUserUnionId(shareUserIdThirdIdentity.getIdentityUnionId());
                    tbWecomChatGroupFissionInvite.setFissionId(fissionId);
                    tbWecomChatGroupFissionInvite.setScene(scene);
                    tbWecomChatGroupFissionInvite.setChatId(wecomChatGroupVO.getChatId());
                    tbWecomChatGroupFissionInvite.setStatus(GroupFissionInviteStatusEnum.NOT_JOINED.getCode());
                    tbWecomChatGroupFissionInvite.setCreateTime(new Date());
                    tbWecomChatGroupFissionInvite.setCreateTime(new Date());
                    tbWecomChatGroupFissionInviteService.save(tbWecomChatGroupFissionInvite);
                }
            }
            return wecomChatGroupVO;
        } else {
            throw new ServiceException("群裂变活动可用群聊暂无");
        }

    }

    @Override
    public String generateMyScene(Long userId, Long fissionId) {
        TbWecomChatGroupFissionScene tbWecomChatGroupFissionScene = tbWecomChatGroupFissionSceneService.getOne(Wrappers.lambdaQuery(TbWecomChatGroupFissionScene.class)
            .eq(TbWecomChatGroupFissionScene::getType, FissionSceneTypeEnum.ONLY_SHARE.getCode())
            .eq(TbWecomChatGroupFissionScene::getUserId, userId)
            .eq(TbWecomChatGroupFissionScene::getFissionId, fissionId));
        if (ObjectUtil.isNotEmpty(tbWecomChatGroupFissionScene)) {
            return tbWecomChatGroupFissionScene.getScene();
        } else {
            long scene = IdWorker.getId();
            TbWecomChatGroupFissionScene add = new TbWecomChatGroupFissionScene();
            add.setId(scene);
            add.setName(String.valueOf(scene));
            add.setType(FissionSceneTypeEnum.USER_SHARE.getCode());
            add.setFissionId(fissionId);
            add.setUserId(userId);
            add.setScene(String.valueOf(scene));
            add.setCreateTime(new Date());
            tbWecomChatGroupFissionSceneService.save(add);
            return add.getScene();
        }
    }

}
